Jx.declare('Jx.Manager', {

	$extend: 'Jx.data.Collection',

	$accessors: {

		ns: '',

		defaultType: '',

		baseType: 'Jx',

		classNameSuffix: ''

	},

	$actions: [

		'create'

	],

	$helpers: {

		Class: 'Jx.Class'

	},

	keyPrefix: 'managed',

	allowCreate: function(operation, type, args, defaultType){

		var Class = this.createTypeConstructor(type, defaultType);

		operation.Class = Class;

		operation.arguments = Jx.isArray(args) ? args : [];

		operation.type = type;

		operation.returnValue = undefined;

		return !!Class;

	},

	allowSetNs: function(operation, ns){

		return Jx.isString( ns, true );

	},

	allowSetDefaultType: function(operation, type){

		return Jx.isString( type, true );

	},

	allowSetBaseType: function(operation, type){

		return Jx.isString( type, true ) && this.$Class.exists(type);

	},

	allowSetClassNameSuffix: function(operation, suffix){

		return Jx.isString( suffix, true );

	},

	allowAdd: function(operation){

		return this.$super(arguments) &&

			Jx.instanceOf(operation.value, this.baseType());

	},

	allowUpdate: function(operation){

		return this.$super(arguments) &&

			Jx.instanceOf(operation.value, this.baseType());

	},

	onCreate: function(operation){

		operation.returnValue = Jx.instantiate( operation.Class.$name, operation.arguments );

	},

	onAfterCreate: function(operation){

		var instance = operation.returnValue,

			id = operation.key;

		if (!id){

			id = this.keyPrefix + (++ this.genKey);

		}

		if (!this.itemByName(id)){

			this.set(id, instance);

			this.dispatch('create', instance, id);

		}

	},

	createTypeConstructor: function(type, defaultType){

		var Class = this.$Class;

		return Class.get( this.formatTypeName(type), true ) ||

			Class.get( this.formatTypeName(defaultType), true ) ||

			Class.get(

				this.formatTypeName(

					this.defaultType()

				),

				true

			);

	},

	typeExists: function(type){

		return this.$Class.exists(

			this.formatTypeName(type)

		);

	},

	formatTypeName: function(name){

		var ns = this.ns(),

			suffix = this.classNameSuffix(),

			returnValue = '';

		if (Jx.isString(name, true)){

			var parts = [ name ];

			if (ns){

				parts.unshift(ns);

			}

			if (suffix){

				parts.push(suffix);

			}

			returnValue = parts.join('.');

		}

		return returnValue;

	}

});
